package com.sz.biz.logistics.ord.service.impl;

import com.google.common.collect.Maps;
import com.sz.biz.common.base.dto.AreaDto;
import com.sz.biz.common.base.dto.CountryModel;
import com.sz.biz.common.base.service.AreaManager;
import com.sz.biz.common.base.service.AreaService;
import com.sz.biz.common.constants.CommCodes;
import com.sz.biz.common.constants.LanguageCode;
import com.sz.biz.logistics.base.entity.Airport;
import com.sz.biz.logistics.base.entity.Port;
import com.sz.biz.logistics.base.service.AirportService;
import com.sz.biz.logistics.base.service.PortService;
import com.sz.biz.logistics.constants.RegionConstants;
import com.sz.biz.logistics.ord.dto.OrderAddressModel;
import com.sz.biz.logistics.ord.service.OrdOrderCommService;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.utils.CollectionUtils;
import com.sz.common.base.utils.ObjectUtils;
import com.sz.common.base.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * Function: TODO: ADD FUNCTION <br>
 * Author: hpeng.wang. <br>
 * Date: 2018-01-02 09:44:00.
 */
@Service
public class OrdOrderCommServiceImpl implements OrdOrderCommService {

    @Autowired
    private AreaManager areaManager;

    @Autowired
    private AreaService areaService;

    @Autowired
    private PortService portService;
    @Autowired
    private AirportService airportService;


    /**
     * 校验地址是否可用，海运，空运，速递统一校验
     */
    @Override
    public boolean checkAddress(OrderAddressModel addressModel) {
        //校验国家
        String countryName = addressModel.getCountryName();
        //校验国家是否为空
        boolean checkVoidResult = checkVoidAddressInfo(countryName);
        if (!checkVoidResult) {
            return false;
        }
        String changeCountryName = changeCountry(countryName);
        List<CountryModel> countryModels = areaService.getCountrysByNameOrCode(countryName);
        if (countryModels.size() == 1) {
            //设置国家编码和名称
            addressModel.setCountryCode(countryModels.get(0).getCode());
            addressModel.setCountryName(countryModels.get(0).getName());
            if (CommCodes.TRANSPORT_LAND == addressModel.getTransportType()) {
                //校验详细地址是否为空
                boolean checkAddressDetailResult = checkVoidAddressInfo(addressModel.getAddress());
                if (!checkAddressDetailResult) {
                    return false;
                }
                if (LanguageCode.CHINA.equals(countryName) || LanguageCode.CN_UPPER.equals(changeCountryName)) {
                    String provinceName = addressModel.getProvinceName();
                    //校验省份是否为空
                    boolean checkProvinceResult = checkVoidAddressInfo(provinceName);
                    if (!checkProvinceResult) {
                        return false;
                    }
                    //校验省份
                    if (provinceName.lastIndexOf(RegionConstants.AreaType.PROVINCE) > 0) {
                        provinceName = provinceName.substring(0, provinceName.length() - 1);
                    }
                    ResultDto resultProvice = areaManager.findByParentId(LanguageCode.CN_UPPER, "0", provinceName, 0, 100);
                    List<AreaDto> areaProviceDtos = (List<AreaDto>) resultProvice.getData();
                    if (!CollectionUtils.isEmpty(areaProviceDtos) && areaProviceDtos.size() == 1) {
                        AreaDto areaProviceDto = areaProviceDtos.get(0);
                        //设置省份ID和名称
                        addressModel.setProvinceId(areaProviceDto.getId());
                        addressModel.setProvinceName(areaProviceDto.getName());

                        String cityName = addressModel.getCityName();
                        //校验城市是否为空
                        boolean checkCityResult = checkVoidAddressInfo(cityName);
                        if (!checkCityResult) {
                            return false;
                        }
                        //校验市
                        if (cityName.lastIndexOf(RegionConstants.AreaType.CITY) > 0) {
                            cityName = cityName.substring(0, cityName.length() - 1);
                        }
                        ResultDto resultCity = areaManager.findByParentId(LanguageCode.CN_UPPER, areaProviceDto.getId(), cityName, 0, 100);
                        List<AreaDto> areaCityDtos = (List<AreaDto>) resultCity.getData();
                        if (!CollectionUtils.isEmpty(areaCityDtos) && areaCityDtos.size() == 1) {
                            AreaDto areaCityDto = areaCityDtos.get(0);
                            //设置城市ID
                            addressModel.setCityId(areaCityDto.getId());
                            addressModel.setCityName(areaCityDto.getName());
                            //获取数据库中该城市下的区县，如果有，则继续校验，如果没有，则不再校验
                            ResultDto resultDistrict = areaManager.findByParentId(LanguageCode.CN_UPPER, areaCityDto.getId(), null, 0, 100);
                            List<AreaDto> areaDistrictDtos = (List<AreaDto>) resultDistrict.getData();
                            if (!CollectionUtils.isEmpty(areaDistrictDtos)) {
                                //校验区、县
                                String districtName = addressModel.getDistrictName();
                                //校验区县是否为空
                                boolean checkDistrictResult = checkVoidAddressInfo(districtName);
                                if (!checkDistrictResult) {
                                    return false;
                                }
                                //精确匹配县，区。
                                AreaDto areaDistrictDto = this.getUniqueTownInfo(areaDistrictDtos, districtName);
                                if (!ObjectUtils.isEmpty(areaDistrictDto)) {
                                    //设置区、县ID，name
                                    addressModel.setDistrictId(areaDistrictDto.getId());
                                    addressModel.setDistrictName(areaDistrictDto.getName());
                                    //获取数据库中该区县下的街道，如果有，则继续校验，如果没有，则不再校验
                                    ResultDto resultStreet = areaManager.findByParentId(LanguageCode.CN_UPPER, areaDistrictDto.getId(), null, 0, 100);
                                    List<AreaDto> areaStreetDtos = (List<AreaDto>) resultStreet.getData();
                                    if (!CollectionUtils.isEmpty(areaStreetDtos)) {
                                        //校验街道
                                        String streetName = addressModel.getStreetName();
                                        //校验街道是否为空
                                        boolean checkStreetResult = checkVoidAddressInfo(streetName);
                                        if (!checkStreetResult) {
                                            return false;
                                        }
                                        //精确匹配街道。
                                        AreaDto areaStreettDto = this.getUniqueTownInfo(areaStreetDtos, streetName);
                                        if (!ObjectUtils.isEmpty(areaStreettDto)) {
                                            //设置街道ID
                                            addressModel.setStreetId(areaStreettDto.getId());
                                            addressModel.setStreetName(areaStreettDto.getName());
                                        } else {
                                            return false;
                                        }
                                    } else {
                                        addressModel.setStreetName(null);
                                    }

                                } else {
                                    return false;
                                }
                            } else {
                                addressModel.setDistrictName(null);
                                addressModel.setStreetName(null);
                            }
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                } else if (!LanguageCode.CHINA.equals(countryName) && !LanguageCode.CN_UPPER.equals(changeCountryName)) {
                    //国外地址
                    String cityName = addressModel.getCityName();
                    //校验城市是否为空
                    boolean checkCityResult = checkVoidAddressInfo(addressModel.getCityName());
                    if (!checkCityResult) {
                        return false;
                    }
                    ResultDto resultCity = areaManager.findByParentId(countryModels.get(0).getCode(), countryModels.get(0).getCode(), cityName, 0, 100);
                    List<AreaDto> areaDtos = (List<AreaDto>) resultCity.getData();
                    //国外城市需要精确匹配
                    if (!CollectionUtils.isEmpty(areaDtos)) {
                        AreaDto areaCityDto = getForeignCity(areaDtos, cityName);
                        if (null != areaCityDto && null != areaCityDto.getId()) {
                            addressModel.setCityId(areaCityDto.getId());
                            addressModel.setCityName(areaCityDto.getName());
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }
            } else if(CommCodes.TRANSPORT_AIR==addressModel.getTransportType()
                    || CommCodes.TRANSPORT_SEA==addressModel.getTransportType()){
                //校验机场或港口是否为空
                boolean checkDistrictResult = checkVoidAddressInfo(addressModel.getDistrictName());
                if (!checkDistrictResult) {
                    return false;
                }
                //若非速递，校验地址的港口或机场信息
                boolean result = this.checkPortOrAirPort(addressModel, String.valueOf(addressModel.getTransportType()));
                if (!result) {
                    return false;
                }
            }else {
                return false;
            }
        } else {
            return false;
        }
        return true;
    }


    /**
     * 校验地址信息是否为空
     * @param addressInfo
     * @return
     */
    private boolean checkVoidAddressInfo(String addressInfo) {
        if (StringUtils.isEmpty(addressInfo)) {
            return false;
        }
        return true;
    }

    private String changeCountry(String countryName) {
        String countryNameResult = "";
        if (LanguageCode.CN_UPPER.equals(countryName.toUpperCase())) {
            countryNameResult = LanguageCode.CN_UPPER;
        }
        return countryNameResult;
    }

    /**
     * 国外城市精确匹配
     * @param areaCityDtos
     * @param cityName
     * @return
     */
    private AreaDto getForeignCity(List<AreaDto> areaCityDtos, String cityName) {
        AreaDto cityDto = null;
        for (AreaDto areaDto : areaCityDtos) {
            if (areaDto.getName().equalsIgnoreCase(cityName)) {
                cityDto = areaDto;
                break;
            }
        }
        return cityDto;
    }

    private boolean checkPortOrAirPort(OrderAddressModel orderAddressModel, String transportType) {
        Map<String, Object> type2Object = Maps.newHashMap();
        boolean isValidFromPort = this.judgePort(orderAddressModel.getDistrictName(), orderAddressModel.getCountryCode(), transportType, type2Object);
        if (!isValidFromPort) {
            return false;
        } else {
            this.setAddressModelAirPortOrPort(type2Object, transportType, orderAddressModel);
        }
        return true;
    }

    /**
     * 根据类型来查询机场或港口的数据是否存在
     *
     * @param param 如果type为为海运传的是中文名称或英文名称，type为机场，传的是三字码
     * @param type  CommCodes.TRANSPORT_SEA 海运 CommCodes.TRANSPORT_AIR 机场
     * @return true 有效的机场或港口，false 无效的机场或港口
     */
    private boolean judgePort(String param, String countryCode, String type, Map<String, Object> type2Object) {
        boolean bFind = false;
        if (!StringUtils.isEmpty(param) && !StringUtils.isEmpty(type)) {
            if (type.equals(String.valueOf(CommCodes.TRANSPORT_SEA))) {
                List<Port> ports = portService.findPortByName(param, countryCode);
                if (!CollectionUtils.isEmpty(ports) && ports.size() > 0) {
                    type2Object.put(String.valueOf(CommCodes.TRANSPORT_SEA), ports.get(0));
                    bFind = true;
                }
            } else if (type.equals(String.valueOf(CommCodes.TRANSPORT_AIR))) {
                Airport airport = airportService.findAirPortByTriadCode(param, countryCode);
                if (!ObjectUtils.isEmpty(airport)) {
                    type2Object.put(String.valueOf(CommCodes.TRANSPORT_AIR), airport);
                    bFind = true;
                }
            }
        }
        return bFind;
    }

    //精确匹配区/县，街道
    private AreaDto getUniqueTownInfo(List<AreaDto> areaDistrictDtos, String orignalDistrictName) {
        AreaDto areaDto = null;
        if (!StringUtils.isEmpty(orignalDistrictName)) {
            for (AreaDto areaTownDto : areaDistrictDtos) {
                if (areaTownDto.getName().startsWith(orignalDistrictName)) {
                    areaDto = areaTownDto;
                    break;
                }
            }
        }
        return areaDto;
    }


    private void setAddressModelAirPortOrPort(Map<String, Object> type2Object, String transportType, OrderAddressModel orderAddressModel) {
        if (!CollectionUtils.isEmpty(type2Object)) {
            Object objectFrom = type2Object.get(transportType);
            if (objectFrom instanceof Airport) {
                Airport airPort = (Airport) objectFrom;
                if (LanguageCode.CN_UPPER.equalsIgnoreCase(orderAddressModel.getCountryCode())) {
                    List<AreaDto> provices = areaManager.findByAreaId(orderAddressModel.getCountryCode(), String.valueOf(airPort.getCityId()));
                    if (!CollectionUtils.isEmpty(provices) && provices.size() == 1) {
                        orderAddressModel.setProvinceId(provices.get(0).getParentId());
                    }
                }
                orderAddressModel.setTransportId(airPort.getId());
                orderAddressModel.setCityId(airPort.getCityId());
            }

            if (objectFrom instanceof Port) {
                Port port = (Port) objectFrom;
                List<AreaDto> portDtos = areaManager.findByAreaId(orderAddressModel.getCountryCode(), String.valueOf(port.getCityId()));
                if (!CollectionUtils.isEmpty(portDtos) && portDtos.size() == 1) {
                    orderAddressModel.setProvinceId(portDtos.get(0).getParentId());
                }
                orderAddressModel.setTransportId(port.getId());
                orderAddressModel.setCityId(port.getCityId());
            }
        }
    }

}
